package org.steven.crm.core.utils;

import org.apache.commons.lang3.StringUtils;

import java.util.*;

/**
 * @Author wuzw
 * @Date 2023/5/17 22:27
 * @Version 1.0
 */
public class TreeUtil {
    /**
     * 构建树形结构
     * @param datas 节点数据
     * @param parentKey 父节点字段
     * @return
     * @throws Exception
     */
    public static List<Map<String, Object>> makeTree(List<Map<String, String>> datas, String parentKey) throws Exception {
        List<Map<String, Object>> menusWithChild = new ArrayList<>();
        for (Map<String, String> menu : datas) {
            Map<String, Object> tmpMenu = new HashMap<>();
            tmpMenu.putAll(menu);
            menusWithChild.add(tmpMenu);
        }

        Map<String, List<Map<String, Object>>> childrenHash = new HashMap<>();
        for (Map<String, Object> tmpMenu : menusWithChild) {
            String parentId = tmpMenu.get(parentKey).toString();
            if (!childrenHash.containsKey(parentId)) {
                childrenHash.put(parentId, new Vector<>());
            }
            childrenHash.get(parentId).add(tmpMenu);
        }


        List<Map<String, Object>> topMenus = new ArrayList<>();
        for (Map<String, Object> menu : menusWithChild) {
            String parentId = menu.get(parentKey).toString();
            if (StringUtils.isEmpty(parentId) || parentId.equals("0")) {
                addChildren(menu, childrenHash);
                topMenus.add(menu);
            }

        }

        removeTreeDataColumn(topMenus, "pid");
        return topMenus;
    }

    private static void addChildren(Map<String, Object> tree, Map<String, List<Map<String, Object>>> childrenHash) {
        String menuID = tree.get("id").toString();
        List<Map<String, Object>> children = childrenHash.get(menuID);
        boolean hasChildren = children != null && children.size() > 0;
        if (hasChildren) {
            for (Map<String, Object> child : children) {
                addChildren(child, childrenHash);
            }

            tree.put("children", children);
        }
    }

    private static void removeTreeDataColumn(List<Map<String, Object>> treeDatas, String column) {
        for (Map<String, Object> data : treeDatas) {
            data.remove(column);
            if (data.containsKey("children")) {
                removeTreeDataColumn((List<Map<String, Object>>) data.get("children"), column);
            }
        }
    }
}
